<?xml version="1.0" encoding="UTF-8"?>

	<!--
		Document : xsd-to-types.xsl Created on : May 30, 2010, 8:25 PM Author
		: fransvanderlek Description: Purpose of transformation follows.
	-->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
	<xsl:output method="xml" indent="yes" />

	<xsl:strip-space elements="*" />

	<xsl:template match="/">
		<xsl:element name="classes">
			<xsl:apply-templates mode="classes"/>
		</xsl:element>
	</xsl:template>

	<xsl:template match="xs:complexType | xs:simpleType | /xs:schema/xs:group" mode="classes">
		<class name="{@name | ../@name}" content="{local-name()}">
			<xsl:apply-templates mode="derivation" />
			<properties>
				<xsl:apply-templates mode="properties"/>
			</properties>
			<xsl:element name="nested-classifiers">
				<xsl:apply-templates  mode="classes"/>
			</xsl:element>
		</class>
	</xsl:template>

	<xsl:template match="//xs:complexType/*/xs:extension | //xs:complexType/*/xs:restriction" mode="derivation">
		<extends>
			<xsl:value-of select="@base" />
		</extends>
		<xsl:apply-templates />
	</xsl:template>

	<xsl:template match="xs:element[@ref]" mode="properties">
		<xsl:variable name="referencedName">
			<xsl:value-of select="@ref" />
		</xsl:variable>

		<xsl:apply-templates mode="properties"
			select="/xs:schema/xs:element[@name=$referencedName]" />
	</xsl:template>

	<!--
		assume element either has type attribute, or has type definition
		inline. so continue applying templates to find out.
	-->
	<xsl:template match="xs:element[@name]" mode="properties">	
		<property>			
			<xsl:apply-templates select="* | @*" mode="properties" />
		</property>		
	</xsl:template>	
	
	<xsl:template match="text()" />

	
	
	<xsl:template match="@name" mode="properties">
	<name><xsl:value-of select="."/></name>
	</xsl:template>
		
	<!--
		in properties mode, matching these will signal that the parent is an
		element by way of xml schema rules. so for the type we use the name of
		type schema type.
	-->
	<xsl:template match="xs:complexType | xs:simpleType" mode="properties">
		<type><xsl:value-of select="../@name"/></type>
		<reference>association</reference>		
	</xsl:template>

	<!-- type given -->
	<xsl:template match="@type" mode="properties">
		<type><xsl:value-of select="."/></type>		
		<xsl:variable name="typeRef" select="." />
<!--		<xsl:message>### look for referenced type : <xsl:value-of select="$typeRef"/>####</xsl:message>-->
		<xsl:choose>
			<xsl:when test="count(/xs:schema/*[@name=$typeRef])>0">
				<reference>association</reference>
			</xsl:when>
			<xsl:otherwise>
				<reference>primitive</reference>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

	<xsl:template match="@maxOccurs[. = 'unbounded' or .>1]" mode="properties">
		<collectionItem>true</collectionItem>		
	</xsl:template>

	<xsl:template match="xs:group[@ref]" mode="properties">
		<property>
			<name><xsl:value-of select="./@ref"/></name>
			<type><xsl:value-of select="./@ref"/></type>
			<reference>association</reference>
		</property>		
	</xsl:template>

<!-- 

	<xsl:template
		match="//*[local-name()='complexType' or local-name()='simpleType' or local-name()='group']">

		<xsl:element name="class">
			<xsl:attribute name="name">
				<xsl:value-of select="@name | ../@name" />
			</xsl:attribute>
			<xsl:attribute name="content">
				<xsl:choose>
					<xsl:when test="local-name()='simpleType'">simple</xsl:when>
					<xsl:otherwise>complex</xsl:otherwise>
				</xsl:choose>								
			</xsl:attribute>

			<xsl:if test="./*/*[local-name()='extension']">
				<extends>
					<xsl:value-of select=".//*[local-name()='extension']/@base" />
				</extends>
			</xsl:if>
			<xsl:variable name="currentAncestorComplexCount">
				<xsl:value-of
					select="count(ancestor-or-self::*[local-name() = 'complexType'])" />
			</xsl:variable>

			<xsl:element name="properties">
				<xsl:for-each
					select=".//*[local-name()='element' and count(ancestor::xs:complexType)=$currentAncestorComplexCount]">
					<xsl:call-template name="add-property" />
				</xsl:for-each>
			</xsl:element>
			<xsl:element name="nested-classifiers">
				<xsl:apply-templates />
			</xsl:element>
		</xsl:element>

	</xsl:template>

	<xsl:template name="add-property">
		<xsl:choose>
			<xsl:when test="@ref">
				<xsl:variable name="referencedName">
					<xsl:value-of select="@ref" />
				</xsl:variable>

				<xsl:for-each
					select="//*[local-name() = 'element' and @name=$referencedName]">
					<xsl:call-template name="add-property" />
				</xsl:for-each>

			</xsl:when>
			<xsl:otherwise>
				<xsl:element name="property">
					<xsl:attribute name="name">
                <xsl:value-of select="@name" />
            </xsl:attribute>
					<xsl:attribute name="type">
                    <xsl:choose>
                    <xsl:when test="not(@type)">
                        <xsl:value-of select="@name" />
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="@type" />
                    </xsl:otherwise>
                    </xsl:choose>
                   </xsl:attribute>
					<xsl:if test="@maxOccurs = 'unbounded' or @maxOccurs >1 ">
						<xsl:attribute name="collectionItem">true</xsl:attribute>
					</xsl:if>
				</xsl:element>
			</xsl:otherwise>

		</xsl:choose>


	</xsl:template>
 -->
</xsl:stylesheet>
